package com.tjetc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tjetc.entity.po.Coupon;
import com.tjetc.entity.po.Order;
import com.tjetc.entity.po.Seckill;
import com.tjetc.mapper.CouponMapper;
import com.tjetc.mapper.OrderMapper;
import com.tjetc.mapper.SeckillMapper;
import com.tjetc.service.ICouponService;
import com.tjetc.utils.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * @author gaoyongxiang
 * @version v1.0
 * @since 2025-10-27
 */
@Service
public class ICouponServiceImpl extends ServiceImpl<CouponMapper, Coupon>implements ICouponService {

    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private SeckillMapper seckillMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public String addSeckillCoupon(Coupon coupon) {
        // 由于我们操作的mapper是针对一个表所以只能操作一个表的对象 如果想要给两个表一起添加数据
        // 1. 调用两个mapper
        // 2. 自己在mapper中写sql
        couponMapper.insert(coupon);
//        save(coupon);
        Seckill seckill = new Seckill();
        seckill.setCouponId(coupon.getId());
        seckill.setStock(coupon.getStock());
        seckill.setBeginTime(coupon.getBeginTime());
        seckill.setEndTime(coupon.getEndTime());
        seckillMapper.insert(seckill);
        //  我们一会扣减库存的操作是在redis中实现  我们一般将库存量放在redis中一份 提高效率
        redisTemplate.opsForValue().set("stock:" + coupon.getId(), coupon.getStock());

        return coupon.getId().toString();
    }



    @Override
    public String seckillCoupon(Integer id) {
        /*
            （1）根据id查询当前优惠券的信息
            （2）判断时间是否是开始时间和结束时间之间（LocalDateTime的API）
            （3）判断库存是否充足
            （4）扣减库存
            （5）生成订单
         */
        Seckill seckill = seckillMapper.selectById(id);
        if (seckill.getBeginTime().isAfter(LocalDateTime.now())) {
            return "未开始";
        }

        if (seckill.getEndTime().isBefore(LocalDateTime.now())) {
            return "已经结束";
        }

        if (seckill.getStock() < 1) {
            return "库存不够";
        }
        //sql update  seckill set stock = stock - 1 where coupon_id = #{}
        UpdateWrapper<Seckill> wrapper = new UpdateWrapper<>();
        wrapper.set("stock", seckill.getStock() - 1);
        wrapper.ge("coupon_id", seckill.getCouponId());
        // 更新库存时多做一步
//        wrapper.ge("stock", seckill.getStock());
        wrapper.gt("stock", 0);
        int row = seckillMapper.update(wrapper);
        if (row < 1) {
            return "扣减库存失败";
        }

        Order order = new Order();
        //order的id自动生成
        // 用户信息 userid 从当前用户进行获取
        order.setUserId(UserContext.getUser().getUserId());
        order.setCouponId(seckill.getCouponId());
        orderMapper.insert(order);
        // 我们一般生成订单后将订单号返回给前端 前端要用这个订单号 唤起支付
        return order.getId().toString();
    }
}
